/*
Copyright (C) 2003  Pierrick Brihaye
pierrick.brihaye@wanadoo.fr

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the
Free Software Foundation, Inc.
59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
or connect to:
http://www.fsf.org/copyleft/gpl.html
*/

package gpl.pierrick.brihaye.aramorph.lucene;

import gpl.pierrick.brihaye.aramorph.AraMorph;

import java.io.IOException;
import java.io.StringReader;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.logging.Logger;

import org.apache.lucene.analysis.TokenFilter;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
import org.apache.lucene.analysis.tokenattributes.TermAttribute;

/** A filter that will filter arabic tokens regarding to their grammatical category.
 * @author Pierrick Brihaye, 2003, Ahmed ElDawy, 2009
 */
public class ArabicGrammaticalFilter extends TokenFilter {
	private static final Logger logger = Logger.getLogger(ArabicGrammaticalFilter.class.getName());
	
	
	private String[] WORTHY_CATEGORIES = {
		"ABBREV",
		"ADJ",
		"ADV",		
		"NOUN",
		"NOUN_PROP",				
		"VERB_IMPERATIVE",
		"VERB_IMPERFECT",
		"VERB_PERFECT",
		"NO_RESULT" //Mainly concerns words that are not in the dictionary (e.g. foreign words)
	};
	
	private String[] UNWORTHY_CATEGORIES = {		
		"CONJ",		
		"DEM_PRON_F",
		"DEM_PRON_FP",
		"DEM_PRON_FS",
		"DEM_PRON_FD",
		"DEM_PRON_MD",
		"DEM_PRON_MP",
		"DEM_PRON_MS",
		"DET",
		"FUNC_WORD",
		"INTERJ",
		"INTERROG",		
		"NO_STEM",	
		"NUMERIC_COMMA",	
		"PART", 
		"PREP",
		"PRON_1P",
		"PRON_1S",
		"PRON_2D",
		"PRON_2FP",
		"PRON_2FS",
		"PRON_2MP",
		"PRON_2MS",
		"PRON_3D",
		"PRON_3FP",
		"PRON_3FS",
		"PRON_3MP",
		"PRON_3MS",
		"REL_PRON",
	};
	
	private Collection<String> worthyCategories = null;
	private Collection<String> unworthyCategories = null;

	private PositionIncrementAttribute posIncrAtt;
	private POSAttribute posAtt;

	/** Constructs a filter that will filter arabic tokens regarding to their grammatical category.
	 * @param input The token stream from a tokenizer
	 */
	public ArabicGrammaticalFilter(TokenStream input) {
		this(input, AraMorph.getNormalizedJDBC());
	}
	
	public ArabicGrammaticalFilter(TokenStream input, AraMorph araMorph) {
		super(input);
		worthyCategories = new HashSet<String>(Arrays.asList(WORTHY_CATEGORIES));
		unworthyCategories = new HashSet<String>(Arrays.asList(UNWORTHY_CATEGORIES));
		
		posIncrAtt = (PositionIncrementAttribute) addAttribute(PositionIncrementAttribute.class);
		posAtt = (POSAttribute) addAttribute(POSAttribute.class);
	}
	
	@Override
	public boolean incrementToken() throws IOException {
		int positionIncrement = 0;
		while (input.incrementToken()) {
			if (worthyCategories.contains(posAtt.getPOS()))
				return true;
			else if (unworthyCategories.contains(posAtt.getPOS()))
				positionIncrement += posIncrAtt.getPositionIncrement();
			else {
				logger.info("Don't know what to do with category : \"" + posAtt.getPOS() + "\" ?");
				return true;
			}
		}
		return false;
	}

	public static void main(String[] args) {
		try {
			String arabicText = "أنا أحب هي";
			ArabicTokenizer at = new ArabicTokenizer(new StringReader(arabicText));
			ArabicGlosser ag = new ArabicGlosser(at);
			ArabicGrammaticalFilter agf = new ArabicGrammaticalFilter(ag);
			while (agf.incrementToken()) {
//				System.out.println(agf.getAttribute(TermAttribute.class).term()+
//						", Gloss:"+agf.getAttribute(GlossAttribute.class).getGloss()+
//						", POS:"+agf.getAttribute(POSAttribute.class).getPOS());
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}
